﻿using System;
using System.Runtime.InteropServices;

namespace 锁屏
{
    public abstract class HookBase
    {
        public HookBase() { }

        #region 扩展方法
        [DllImport("user32.dll")]
        public static extern short GetAsyncKeyState(int vKey);

        /// <summary>
        /// Loads the library.
        /// </summary>
        /// <param name="lpFileName">Name of the library</param>
        /// <returns>A handle to the library</returns>
        [DllImport("kernel32.dll")]
        public static extern IntPtr LoadLibrary(string lpFileName);
        //模拟键盘事件 
        [DllImport("user32.dll")]
        public static extern void keybd_event(Byte bVk, Byte bScan, Int32 dwFlags, Int32 dwExtraInfo);//释放按键的常量 
        //发送消息
        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
        [DllImport("user32.dll")]
        protected static extern void mouse_event(UInt32 dwFlags, UInt32 dx, UInt32 dy, UInt32 dwData, IntPtr dwExtraInfo);
        [DllImport("user32.dll", EntryPoint = "SetCursorPos")]
        public static extern int SetCursorPos(int x, int y);

        [DllImport("user32.dll")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        /// <summary>
        /// 安装钩子
        /// </summary>
        /// <param name="idHook"></param>
        /// <param name="lpfn"></param>
        /// <param name="hInstance"></param>
        /// <param name="threadId"></param>
        /// <returns></returns>
        [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr pInstance, int threadId);

        /// <summary>
        /// 卸载钩子
        /// </summary>
        /// <param name="idHook"></param>
        /// <returns></returns>
        [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle);

        /// <summary>
        /// 传递钩子
        /// </summary>
        /// <param name="pHookHandle">是您自己的钩子函数的句柄。用该句柄可以遍历钩子链</param>
        /// <param name="nCode">把传入的参数简单传给CallNextHookEx即可</param>
        /// <param name="wParam">把传入的参数简单传给CallNextHookEx即可</param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(IntPtr pHookHandle, int nCode,
            Int32 wParam, IntPtr lParam);
        #endregion

        /// <summary>
        /// 钩子委托声明
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);

        /// <summary>
        /// 钩子是否正在侦听
        /// </summary>
        public bool IsListening { get; set; }

        /// <summary>
        /// 钩子委托实例
        /// </summary>
        private HookProc m_HookProcedure;

        /// <summary>
        /// 底层钩子类型
        /// </summary>
        protected int idHook;

        /// <summary>
        /// 当前句柄
        /// </summary>
        protected IntPtr CurPtr = IntPtr.Zero;

        /// <summary>
        /// 句柄标题
        /// </summary>
        public const string AppTitle = "Warcraft III";//"a.txt - 记事本";// "Form1";//"Form1";//Warcraft III";//"Form1"; //

        /// <summary>
        /// 钩子处理函数
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        protected abstract int HookProcInstance(int nCode, Int32 wParam, IntPtr lParam);


        /// <summary>
        /// 启动钩子
        /// </summary>
        /// <returns></returns>
        public bool Begin()
        {
            if (IsListening)
            {
                return true;
            }
            //IntPtr pInstance = (IntPtr)4194304;
            IntPtr pInstance = LoadLibrary("user32");
            //IntPtr pInstance = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
            this.m_HookProcedure = new HookProc(HookProcInstance);
            // 设置钩子            
            this.CurPtr = SetWindowsHookEx(idHook, m_HookProcedure, pInstance, 0);
            if (this.CurPtr == IntPtr.Zero)
            {
                return false;
            }
            IsListening = true;
            return true;
        }
        /// <summary>
        /// 停止钩子
        /// </summary>
        /// <returns></returns>
        public bool Stop()
        {
            if (!IsListening)
            {
                return true;
            }
            // 卸载钩子
            UnhookWindowsHookEx(CurPtr);
            CurPtr = IntPtr.Zero;
            IsListening = false;
            return true;
        }

    }
}
